# Script to fix command not found errors by adding directories to PATH
# Run this script to locate and fix missing commands

param (
    [Parameter(Mandatory=$false)]
    [string]$CommandName = "pdf2zh",
    
    [Parameter(Mandatory=$false)]
    [string]$SearchDirectory = $null,
    
    [Parameter(Mandatory=$false)]
    [ValidateSet("User", "System")]
    [string]$Target = "User"
)

# Check if running with administrator privileges
function Test-Admin {
    $currentUser = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
    return $currentUser.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}

# Administrator privileges required for system variables
if ($Target -eq "System" -and -not (Test-Admin)) {
    Write-Error "Administrator privileges required to modify system environment variables. Please restart this script as Administrator."
    exit 1
}

# Function to search for a command in a directory and its subdirectories
function Find-Command {
    param (
        [string]$CommandToFind,
        [string]$Directory
    )
    
    # Add file extensions to search for
    $extensions = @(".exe", ".bat", ".cmd", ".ps1", ".py", ".vbs", "")
    $found = @()
    
    foreach ($ext in $extensions) {
        $fileName = "$CommandToFind$ext"
        Write-Output "Searching for $fileName in $Directory and subdirectories..."
        $files = Get-ChildItem -Path $Directory -Filter $fileName -Recurse -ErrorAction SilentlyContinue
        foreach ($file in $files) {
            if ($file.PSIsContainer -eq $false) {
                $found += $file.FullName
            }
        }
    }
    
    return $found
}

# Function to check common directories for the command
function Find-CommandInCommonDirectories {
    param (
        [string]$CommandToFind
    )
    
    $found = @()
    
    # Get PATH directories
    $pathDirs = $env:PATH -split ";"
    
    # Add common program directories
    $commonDirs = @(
        "${env:ProgramFiles}",
        "${env:ProgramFiles(x86)}",
        "${env:USERPROFILE}\AppData\Local\Programs",
        "${env:USERPROFILE}\AppData\Local",
        "${env:USERPROFILE}\AppData\Roaming",
        "${env:ProgramData}",
        "C:\tools",
        "D:\tools",
        "C:\Program Files\Python*",
        "C:\Python*",
        "C:\Anaconda*",
        "C:\ProgramData\Anaconda*",
        "${env:USERPROFILE}\Anaconda*",
        "${env:USERPROFILE}\AppData\Local\Programs\Python*"
    )
    
    $allDirs = $pathDirs + $commonDirs
    $processedDirs = @{}
    
    foreach ($dir in $allDirs) {
        # Skip empty entries or already processed directories
        if ([string]::IsNullOrWhiteSpace($dir) -or $processedDirs.ContainsKey($dir)) {
            continue
        }
        
        $processedDirs[$dir] = $true
        
        # Skip directories that don't exist
        if (-not (Test-Path $dir)) {
            continue
        }
        
        # Try to resolve wildcards
        if ($dir -like "*`**") {
            $resolvedDirs = Resolve-Path $dir -ErrorAction SilentlyContinue
            if ($resolvedDirs) {
                foreach ($resolvedDir in $resolvedDirs) {
                    $foundFiles = Find-Command -CommandToFind $CommandToFind -Directory $resolvedDir
                    $found += $foundFiles
                }
            }
        } else {
            $foundFiles = Find-Command -CommandToFind $CommandToFind -Directory $dir
            $found += $foundFiles
        }
    }
    
    return $found
}

Write-Output "Searching for the '$CommandName' command..."

$commandPaths = @()

# If search directory is provided, search there
if ($SearchDirectory) {
    if (Test-Path $SearchDirectory) {
        $commandPaths += Find-Command -CommandToFind $CommandName -Directory $SearchDirectory
    } else {
        Write-Warning "The specified search directory does not exist: $SearchDirectory"
    }
}

# Also search in common directories
$commandPaths += Find-CommandInCommonDirectories -CommandToFind $CommandName

# Remove duplicates
$uniqueCommandPaths = $commandPaths | Select-Object -Unique

# Display results
if ($uniqueCommandPaths.Count -eq 0) {
    Write-Output "The '$CommandName' command was not found."
    Write-Output "Would you like to provide a custom directory path to search? (Y/N)"
    $response = Read-Host
    if ($response -eq "Y" -or $response -eq "y") {
        Write-Output "Enter the directory path to search:"
        $customDir = Read-Host
        if (Test-Path $customDir) {
            $customPaths = Find-Command -CommandToFind $CommandName -Directory $customDir
            if ($customPaths.Count -gt 0) {
                $uniqueCommandPaths = $customPaths | Select-Object -Unique
            } else {
                Write-Output "The '$CommandName' command was not found in the specified directory."
                exit 0
            }
        } else {
            Write-Output "The specified directory does not exist."
            exit 0
        }
    } else {
        exit 0
    }
} else {
    Write-Output "Found the following locations for the '$CommandName' command:"
    for ($i = 0; $i -lt $uniqueCommandPaths.Count; $i++) {
        Write-Output "[$i] $($uniqueCommandPaths[$i])"
    }
    
    Write-Output "Which location would you like to add to PATH? (Enter the number, or 'A' for all, or 'N' for none)"
    $selection = Read-Host
    
    $directoriesToAdd = @()
    
    if ($selection -eq "A" -or $selection -eq "a") {
        # Add all directories
        foreach ($path in $uniqueCommandPaths) {
            $directoriesToAdd += (Split-Path -Parent $path)
        }
    } elseif ($selection -ne "N" -and $selection -ne "n") {
        # Try to parse as number
        try {
            $index = [int]$selection
            if ($index -ge 0 -and $index -lt $uniqueCommandPaths.Count) {
                $directoriesToAdd += (Split-Path -Parent $uniqueCommandPaths[$index])
            } else {
                Write-Output "Invalid selection."
                exit 0
            }
        } catch {
            Write-Output "Invalid selection."
            exit 0
        }
    } else {
        Write-Output "No directories will be added to PATH."
        exit 0
    }
    
    # Remove duplicates from directories to add
    $uniqueDirectoriesToAdd = $directoriesToAdd | Select-Object -Unique
    
    # Add selected directories to PATH
    foreach ($dir in $uniqueDirectoriesToAdd) {
        Write-Output "Adding directory to PATH: $dir"
        & ".\Add-PathToEnvironment.ps1" -PathToAdd $dir -Target $Target
    }
    
    Write-Output "You can now try using the '$CommandName' command in a new PowerShell window."
} 